package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.PasswordConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.EmployeeDTO;
import com.sky.dto.EmployeeLoginDTO;
import com.sky.dto.EmployeePageQueryDTO;
import com.sky.entity.Employee;
import com.sky.exception.AccountLockedException;
import com.sky.exception.AccountNotFoundException;
import com.sky.exception.PasswordErrorException;
import com.sky.mapper.EmployeeMapper;
import com.sky.result.PageResult;
import com.sky.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 员工登录
     *
     * @param employeeLoginDTO 登录接口传递的参数信息
     * @return employee 员工实体
     */
    public Employee login(EmployeeLoginDTO employeeLoginDTO) {
        String username = employeeLoginDTO.getUsername();
        String password = employeeLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        Employee employee = employeeMapper.getByUsername(username);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (employee == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对 ---- 对前端传递的密码加密处理， DigestUtils 是java提供的工具类
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(employee.getPassword())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        if (employee.getStatus() == StatusConstant.DISABLE) {
            //账号被锁定
            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
        }

        //3、返回实体对象
        return employee;
    }

    /**
     * 新增员工 这里才是具体实现逻辑的地方
     * 这个方法主要做两件事情，1、将前端传递的数据，转换成实体； 2、插入条数据
     * @param employeeDTO 员工DTO，前端调用新增员工接口传递给接口的参数类型
     */
    public void save(EmployeeDTO employeeDTO) {
        // 做对象转换，将EmployeeDTO转换成我们需要的实体
        Employee employee = new Employee();
    // 因为前端传递的数据和实体的字段是一至的，所以可以使用一个工具类,可以理解成java中的对象复制； BeanUtils工具类
        BeanUtils.copyProperties(employeeDTO, employee); // 拷贝（源、目标对象）
    // 在补全其他字段，比如status、password、等等，补全那个字段就用 实体.set属性名 的方式
        // StatusConstant是一个常量类，用于状态管理
        employee.setStatus(StatusConstant.ENABLE);
        // PasswordConstant也是常量类, DigestUtils工具类用于md5加密
        log.info("这个加密的是什么,{}", PasswordConstant.DEFAULT_PASSWORD.getBytes());
        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));
        // 设置当前创建时间和修改时间 LocalDateTime.now() 获取当前时间
        employee.setCreateTime(LocalDateTime.now());
        employee.setUpdateTime(LocalDateTime.now());

        // 设置当前记录创建人的ID和修改人的ID   获取线程中的用户ID，BaseContext是一个上下文对象，这个对象中主要通过ThreadLocal本地线程传递上下文数据
        employee.setCreateUser(BaseContext.getCurrentId());
        employee.setUpdateUser(BaseContext.getCurrentId());

        //  调用持久层方法存入数据库 employeeMapper 就是持久层
        employeeMapper.insert(employee);

    }

    /**
     * 员工分页查询接口参数 -- 方法实现
     * @param employeePageQueryDTO 员工分页查询接口-前端传递参数
     * @return PageResult 对象
     */
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        // 正常使用sql语句需要需要通过limit关键字进行查询，例: select * from employee limit 0, 10 意思是从employee这个表中从第一条开始查询10数据
        // 在项目中通过插件查询数据pagehelper插件查询，在根目录中的pom.xml文件引入插件
        // 开始分页查询
        PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());
        // 编写查询数据库代码
        Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);
        // 获取分页数据
        long total = page.getTotal();
        List<Employee> records = page.getResult();
        // 返回result对象
        return new PageResult(total, records);
    }

}
